Add stubs for the stdlib _colorize module - #16370
Conversation
`_colorize` has been available since Python 3.13 and gained the experimental theming API in 3.14, which was extended considerably in 3.15. The stub covers all three versions: - 3.13+: `COLORIZE`, `ANSIColors`, `NoColors`, `get_colors`, `can_colorize` - 3.14+: `ColorCodes`, `decolor`, `ThemeSection`, the `Argparse`, `Syntax`, `Traceback` and `Unittest` sections, `Theme`, `get_theme` and `set_theme` - 3.15+: `CursesColors`, `BackgroundStyle`, ten further theme sections, and the `kw_only` dataclass signatures that 3.15 switched to `attr` and `code` are loop variables that leak into the module namespace, and `BackgroundStyle` is declared with the `type` statement, which stubtest compares against the alias value; all three are allowlisted. Closes python#16361
|
According to mypy_primer, this change has no effect on the checked open source code. 🤖🎉 |
srittau
left a comment
There was a problem hiding this comment.
Not a full review yet, but a few things I noticed. In general, the stub file should use the same ordering as the implementation, even if it means repeating version info checks.
| BOLD: str | ||
| GREY: str | ||
|
|
||
| NoColors: ANSIColors |
There was a problem hiding this comment.
| NoColors: ANSIColors | |
| NoColors: Final[ANSIColors] |
| if sys.version_info >= (3, 14): | ||
| ColorCodes: set[str] |
There was a problem hiding this comment.
Let's move this directly above NoColors so it matches the source order. Also let's make it final.
| def get_colors(colorize: bool = False, *, file: IO[str] | IO[bytes] | None = None) -> ANSIColors: ... | ||
| def can_colorize(*, file: IO[str] | IO[bytes] | None = None) -> bool: ... |
There was a problem hiding this comment.
IO should be avoided in argument positions. In this case it should be a protocol with one optional item fileno. Since optional protocol items are not yet supported (see python/typing#601), the best we can do is probably something like this:
| def get_colors(colorize: bool = False, *, file: IO[str] | IO[bytes] | None = None) -> ANSIColors: ... | |
| def can_colorize(*, file: IO[str] | IO[bytes] | None = None) -> bool: ... | |
| # A protocol with an optional `fileno(self) -> int: ...` member. | |
| _MaySupportFileno: TypeAlias = Any | |
| def get_colors(colorize: bool = False, *, file: _MaySupportFileno | None = None) -> ANSIColors: ... | |
| def can_colorize(*, file: _MaySupportFileno | None = None) -> bool: ... |
_colorizehas been available since Python 3.13 and gained the experimental theming API in 3.14, which was extended considerably in 3.15. The stub covers all three versions:COLORIZE,ANSIColors,NoColors,get_colors,can_colorizeColorCodes,decolor,ThemeSection, theArgparse,Syntax,TracebackandUnittestsections,Theme,get_themeandset_themeCursesColors,BackgroundStyle, ten further theme sections, and thekw_onlydataclass signatures that 3.15 switched toattrandcodeare loop variables that leak into the module namespace, andBackgroundStyleis declared with thetypestatement, which stubtest compares against the alias value; all three are allowlisted.Closes #16361